#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
#include <vector>

#define PROGRAM 1 // 程序	PROGRAM
#define SUBPROG 2 // 分程序	SUBPROG
#define CONSTANTDECLARE 3 // 常量说明部分	CONSTANTDECLARE
#define CONSTANTDEFINE 4 // 常量定义	CONSTANTDEFINE
#define VARIABLEDECLARE 5 // 变量说明部分	VARIABLEDECLARE
#define PROCEDUREDECLARE 6 // 过程说明部分	PROCEDUREDECLARE
#define PROCEDUREHEAD 7 // 过程首部	PROCEDUREHEAD
#define SENTENCE 8 // 语句	SENTENCE
#define ASSIGNMENT 9 // 赋值语句	ASSIGNMENT
#define COMBINED 10 // 复合语句	COMBINED
#define CONDITION 11 // 条件	CONDITION
#define EXPRESSION 12 // 表达式	EXPRESSION
#define ITEM 13 // 项	ITEM
#define FACTOR 14 // 因子	FACTOR
#define IFSENTENCE 15 // 条件语句	IFSENTENCE
#define CALLSENTENCE 16 // 过程调用语句	CALLSENTENCE
#define WHILESENTENCE 17 // 当型循环语句	WHILESENTENCE
#define READSENTENCE 18 // 读语句	READSENTENCE
#define WRITESENTENCE 19 // 写语句	WRITESENTENCE
#define EMPTY 20 // 空语句	EMPTY
#define NUMBER 21 // 无符号整数
#define IDENTIFIER 22 // 标识符
#define OPERATOR 23 // 运算符
#define DELIMITER 24 // 分隔符
#define KEYWORD 25 // 关键字

/*
    Word 单词
    type : 0 1 2 3 4 表示单词类型
        0 -> 关键字
        1 -> 运算符
        2 -> 分隔符
        3 -> 数字
        4 -> 标识符
        -1 -> 未分配
    value : 单词内容
    checkError : 检查是否有错误
    output : 输出word
*/
class WORD {
public:
    int type;
    std::string value;
    WORD()
    {
        type = -1;
        value.clear();
    }
    WORD(int type, std::string value)
    {
        if (type == 3) {
            for ( ; value.front() == '0' && value.length() > 1 ; ) {
                value.erase(value.begin());
            }
        }
        this->type = type;
        this->value = value;
    }
    ~WORD()
    {
    }
    bool checkError()
    {
        if (type == 4) {
            if (value.length() > 10) {
                return 1;
            }
        }
        return 0;
    }
    void output()
    {
        if (type == 3) {
            std::cout << "NUMBER ";
        }
        if (type == 4) {
            std::cout << "IDENTIFIER ";
        }
        std::cout << value << std::endl;
    }
};

/*
    CP 编译程序
    input : 输入字符串
    word : 单词数组
    error : 处理错误
    inputString : 输入函数
    lexicalAnalysis : 词法分析
    outputWord : 输出单词
    checkKeyword : 检查是否为关键字
    checkOperator : 检查是否为运算符
    checkDelimiter : 检查是否为分隔符
    checkNUMBER : 检查是否为数组
    checkIDENTIFIER : 检查是否为标识符
    isEnd : 检查是否为非数字或字母
*/
class CP {
public:
    class TreeNode {
    public:
        std::string name;
        std::vector<int> childId;
        TreeNode(std::string name)
        {
            name = name;
            childId.clear();
        }
    };

    class Addr {
    public:
        int lo, addrs;
        Addr(int lo, int addrs)
        {
            this->lo = lo;
            this->addrs = addrs;
        }
    };

    class Instr {
    public:
        int lo, addrs;
        std::string f;
        Instr(std::string f, int lo, int addrs)
        {
            this->f = f;
            this->lo = lo;
            this->addrs = addrs;
        }
    };

    class Line {
    public:
        std::string name, k;
        int lev, val, adr;
        Line()
        {
            this->name = "";
            this->k = "";
            this->lev = 0;
            this->val = 0;
            this->adr = 0;
        }
        Line(std::string name, std::string k, int lev, int val, int adr)
        {
            this->name = name;
            this->k = k;
            this->lev = lev;
            this->val = val;
            this->adr = adr;
        }
    };
    class Table {
    public:
        std::vector<Line> line;
        int tIndex, lIndex, size;
        Table()
        {
            tIndex = lIndex = -1;
            size = 3;
        }
        Table(int T, int L)
        {
            tIndex = T;
            lIndex = L;
            size = 3;
        }
    };

    std::string input;
    std::vector<WORD> word;
    std::set<std::string> Keyword, Operator, Delimiter;

    std::vector<TreeNode> root;
    std::vector<Instr> instrSet;
    int indexPointer, curNode;
    int nestcnt;
    std::string line;
    std::vector<std::string> value;
    std::vector<int> type;

    std::vector<Table> allT;
    int LEV, TX, nowAdr;

    CP()
    {
        input.clear();
        {
            Keyword.insert("CONST");
            Keyword.insert("VAR");
            Keyword.insert("PROCEDURE");
            Keyword.insert("BEGIN");
            Keyword.insert("END");
            Keyword.insert("ODD");
            Keyword.insert("IF");
            Keyword.insert("THEN");
            Keyword.insert("CALL");
            Keyword.insert("WHILE");
            Keyword.insert("DO");
            Keyword.insert("READ");
            Keyword.insert("WRITE");
            Operator.insert("=");
            Operator.insert(":=");
            Operator.insert("+");
            Operator.insert("-");
            Operator.insert("*");
            Operator.insert("/");
            Operator.insert("#");
            Operator.insert("<");
            Operator.insert("<=");
            Operator.insert(">");
            Operator.insert(">=");
            Delimiter.insert(";");
            Delimiter.insert(",");
            Delimiter.insert(".");
            Delimiter.insert("(");
            Delimiter.insert(")");
        }
        indexPointer = 0;
        nestcnt = 0;
        curNode = 0;
        LEV = TX = 0;
        nowAdr = 3;
        allT.push_back(Table());
    }
    ~CP() { }
    void error()
    {
        puts("Lexical Error");
        exit(0);
    }
    void inputString()
    {
        std::string s;
        for ( ; std::getline(std::cin, s) ; ) {
            input += s;
            input += "\n";
        }
        for (auto& i : input) {
            if (i <= 'z' && i >= 'a')
                i = toupper(i);
            if (i < 33 || i == 127)
                i = (char)32;
        }
    }
    bool checkKeyword(std::string x)
    {
        if (Keyword.find(x) != Keyword.end())
            return 1;
        else
            return 0;
    }
    bool checkOperator(std::string x)
    {
        if (Operator.find(x) != Operator.end())
            return 1;
        else
            return 0;
    }
    bool checkDelimiter(std::string x)
    {
        if (Delimiter.find(x) != Delimiter.end())
            return 1;
        else
            return 0;
    }
    bool checkNUMBER(std::string x)
    {
        if (x.begin() == x.end())
            return 0;
        for (auto& i : x) {
            if (i > '9' || i < '0')
                return 0;
        }
        return 1;
    }
    bool checkIDENTIFIER(std::string x)
    {
        if (x.begin() == x.end())
            return 0;
        if (x[0] > 'Z' || x[0] < 'A')
            return 0;
        for (auto& i : x) {
            if ((i > '9' || i < '0') && (x[0] > 'Z' || x[0] < 'A'))
                return 0;
        }
        return 1;
    }
    bool isEnd(char c)
    {
        if (c >= '0' && c <= '9')
            return 0;
        if (c >= 'A' && c <= 'Z')
            return 0;
        return 1;
    }
    void lexicalAnalysis()
    {
        input.push_back(char(32));
        std::string x;
        for (auto& i : input) {
            if (checkDelimiter(x)) {
                word.emplace_back(2, x);
                x.clear();
                if (i != 32)
                    x.push_back(i);
                continue;
            } else if (checkOperator(x)) {
                if (checkOperator(x + i)) {
                    if (i != 32)
                        x.push_back(i);
                } else {
                    word.emplace_back(1, x);
                    x.clear();
                    if (i != 32)
                        x.push_back(i);
                }
                continue;
            }
            if (isEnd(i)) {
                if (checkKeyword(x)) {
                    word.emplace_back(0, x);
                    x.clear();
                    if (i != 32)
                        x.push_back(i);
                } else if (checkNUMBER(x)) {
                    word.emplace_back(3, x);
                    x.clear();
                    if (i != 32)
                        x.push_back(i);
                } else if (checkIDENTIFIER(x)) {
                    word.emplace_back(4, x);
                    x.clear();
                    if (i != 32)
                        x.push_back(i);
                } else {
                    if (x == "") {
                        if (i != 32)
                            x.push_back(i);
                    } else {
                        if (checkOperator(x + i)) {
                            x.push_back(i);
                        } else
                            error();
                    }
                }
            } else {
                if (i != 32)
                    x.push_back(i);
            }
        }
    }
    void wordCheck()
    {
        for (auto& i : word) {
            if (i.checkError()) {
                error();
                return;
            }
        }
    }
    int addNode(std::string name)
    {
        root.push_back(TreeNode(name));
        return curNode++;
    }
    int addNode(int fa, std::string name)
    {
        root.push_back(TreeNode(name));
        root[fa].childId.push_back(curNode);
        return curNode++;
    }
    int addNode(int fa)
    {
        root.push_back(TreeNode(value[indexPointer++]));
        root[fa].childId.push_back(curNode);
        return curNode++;
    }
    bool testProgram();
    bool testSubProgram(int lastId, bool Main, int TableIndex, int LineIndex);
    bool testConstantDeclare(int lastId);
    bool testConstantDefine(int lastId);
    bool testVariableDeclare(int lastId);
    bool testProcedureDeclare(int lastId);
    bool testProcedureHead(int lastId, int& tIndex, int& lIndex);
    bool testSentence(int lastId);
    bool testAssignment(int lastId);
    bool testCombined(int lastId);
    bool testCondition(int lastId);
    bool testExpression(int lastId);
    bool testItem(int lastId);
    bool testFactor(int lastId);
    bool testRelationOp(int lastId);
    bool testIfSentence(int lastId);
    bool testCallSentence(int lastId);
    bool testWhileSentence(int lastId);
    bool testReadSentence(int lastId);
    bool testWriteSentence(int lastId);
    bool testEmptySentence(int lastId);

    bool exsitna(std::string name, int index)
    {
        for (int i = 0; i < allT[index].line.size(); i++) {
            if (allT[index].line[i].name == name) {
                return true;
            }
        }
        return false;
    }

    Addr findAd(std::string name, bool flag)
    {
        int index = TX, lev = 0;
        for ( ; index != -1 ; ) {
            if (flag) {
                for (int i = 0; i < allT[index].line.size(); i++) {
                    if (allT[index].line[i].name == name && allT[index].line[i].k == "PROCEDURE") {
                        Addr addrs(lev, allT[index].line[i].adr);
                        return addrs;
                    }
                }
            } else {
                for (int i = 0; i < allT[index].line.size(); i++) {
                    if (allT[index].line[i].name == name && allT[index].line[i].k != "PROCEDURE") {
                        if (allT[index].line[i].k == "VARIABLE") {
                            Addr addrs(lev, allT[index].line[i].adr);
                            return addrs;
                        } else {
                            Addr addrs(-1, allT[index].line[i].val);
                            return addrs;
                        }
                    }
                }
            }
            index = allT[index].tIndex;
            lev++;
        }
        Addr addrs(-1, -1);
        return addrs;
    }
    void pushInstr(std::string f, int l, int a)
    {
        instrSet.push_back(Instr(f, l, a));
    }
    void printInstr()
    {
        for (int i = 0; i < instrSet.size(); i++) {
            std::cout << instrSet[i].f << " " << instrSet[i].lo << " " << instrSet[i].addrs << std::endl;
        }
    }
    bool check()
    {
        if (indexPointer > value.size()) {
            return false;
        } else {
            return true;
        }
    }
};

bool CP::testProgram()
{
    int fa = addNode("PROGRAM");

    if (indexPointer >= value.size())
        return false;
    pushInstr("JMP", 0, 0);

    if (!testSubProgram(fa, true, 0, 0))
        return false;

    if (indexPointer == value.size() - 1 && value[indexPointer] == ".") {
        addNode(fa, ".");
        return true;
    } else
        return false;
}

bool CP::testSubProgram(int lastId, bool Main, int TableIndex, int LineIndex)
{
    int fa = addNode(lastId, "SUBPROG");
    if (indexPointer > value.size())
        return false;

    if (value[indexPointer] == "CONST") {
        if (!testConstantDeclare(fa)) {
            return false;
        }
    }
    if (value[indexPointer] == "VAR") {
        if (!testVariableDeclare(fa)) {
            return false;
        }
    }
    if (value[indexPointer] == "PROCEDURE") {
        ++nestcnt;
        if (!testProcedureDeclare(fa)) {
            return false;
        } 
    }
    pushInstr("INT", 0, 3);
    int Idx = instrSet.size() - 1;
    if (Main) {
        Main = false;
        instrSet[0].addrs = Idx;
    } else {
        allT[TableIndex].line[LineIndex].adr = Idx;
    }

    if (!testSentence(fa))
        return false;

    instrSet[Idx].addrs = allT[TX].size;
    pushInstr("OPR", 0, 0); 
    return true;
}

bool CP::testConstantDeclare(int lastId)
{
    int fa = addNode(lastId, "CONSTANTDECLARE");
    if (indexPointer > value.size() || value[indexPointer] != "CONST") 
        return false;
    addNode(fa);
    if (!testConstantDefine(fa))
        return false;
    for ( ; value[indexPointer] == "," ; ) {
        addNode(fa);
        if (!testConstantDefine(fa)) {
            return false;
        }
    }

    if (value[indexPointer] != ";")
        return false;
    addNode(fa);
    return true;
}

bool CP::testConstantDefine(int lastId)
{
    int fa = addNode(lastId, "CONSTANTDEFINE");
    if (indexPointer > value.size() || type[indexPointer] != 4)
        return false;
    Line tl(value[indexPointer], "CONSTANT", 0, 0, 0);

    addNode(fa);
    if (value[indexPointer] != "=")
        return false;
    addNode(fa);
    if (type[indexPointer] != 3)
        return false;
    tl.val = atoi(value[indexPointer].c_str());
    addNode(fa);
    if (!exsitna(tl.name, TX)) {
        allT[TX].line.push_back(tl);
    } else
        return false;
    return true;
}

bool CP::testVariableDeclare(int lastId)
{
    int fa = addNode(lastId, "VARIABLEDECLARE");
    if (indexPointer > value.size() || value[indexPointer] != "VAR")
        return false;
    addNode(fa);
    if (type[indexPointer] != 4)
        return false;
    Line tl(value[indexPointer], "VARIABLE", LEV, 0, nowAdr++);
    if (!exsitna(tl.name, TX)) {
        allT[TX].line.push_back(tl);
        allT[TX].size += 1;
    } else
        return false;
    addNode(fa);
    for ( ; value[indexPointer] == "," ; ) {
        addNode(fa);
        if (type[indexPointer] != 4) {
            return false;
        }
        Line tl(value[indexPointer], "VARIABLE", LEV, 0, nowAdr++);
        if (!exsitna(tl.name, TX)) {
            allT[TX].line.push_back(tl);
            allT[TX].size += 1;
        } else {
            return false;
        }
        addNode(fa);
    }
    if (value[indexPointer] != ";")
        return false;
    addNode(fa);
    return true;
}

bool CP::testProcedureDeclare(int lastId)
{
    LEV += 1;
    if (LEV > 3)
        return false;
    int fa = addNode(lastId, "PROCEDUREDECLARE");
    if (indexPointer > value.size())
        return false;
    int tIndex, lIndex;

    if (!testProcedureHead(fa, tIndex, lIndex))
        return false;
    if (!testSubProgram(fa, false, tIndex, lIndex))
        return false;
    if (value[indexPointer] != ";")
        return false;
    addNode(fa);
    LEV -= 1;
    int ti = allT[TX].tIndex;
    int li = allT[TX].lIndex;
    TX = ti;
    nowAdr = allT[TX].line[li].adr + 1;
    for ( ; value[indexPointer] == "PROCEDURE" ; ) {
        if (!testProcedureDeclare(fa)) {
            return false;
        }
    }
    return true;
}

bool CP::testProcedureHead(int lastId, int& tIndex, int& lIndex)
{
    int fa = addNode(lastId, "PROCEDUREHEAD");
    if (indexPointer > value.size() || value[indexPointer] != "PROCEDURE")
        return false;
    addNode(fa);
    if (type[indexPointer] != 4)
        return false;
    allT.push_back(Table());
    int nowTX = allT.size() - 1;
    Line tl(value[indexPointer], "PROCEDURE", LEV - 1, 0, instrSet.size());
    if (!exsitna(tl.name, TX)) {
        allT[TX].line.push_back(tl);
        tIndex = TX;
        lIndex = allT[TX].line.size() - 1;
        allT[nowTX].tIndex = TX;
        allT[nowTX].lIndex = allT[TX].line.size() - 1;
        TX = nowTX;
        nowAdr = 3;
    } else
        return false;
    addNode(fa);
    if (value[indexPointer] != ";")
        return false;
    addNode(fa);
    return true;
}

bool CP::testSentence(int lastId)
{
    int fa = addNode(lastId, "SENTENCE");
    if (indexPointer > value.size())
        return false;
    if (type[indexPointer] != 4 && value[indexPointer] != "IF" && value[indexPointer] != "WHILE"
        && value[indexPointer] != "CALL" && value[indexPointer] != "READ" && value[indexPointer] != "WRITE"
        && value[indexPointer] != "BEGIN") {
        testEmptySentence(fa);
    }
    if (type[indexPointer] == 4 && !testAssignment(fa))
        return false;
    if (value[indexPointer] == "IF" && !testIfSentence(fa))
        return false;
    if (value[indexPointer] == "WHILE" && !testWhileSentence(fa))
        return false;
    if (value[indexPointer] == "CALL" && !testCallSentence(fa))
        return false;
    if (value[indexPointer] == "READ" && !testReadSentence(fa))
        return false;
    if (value[indexPointer] == "WRITE" && !testWriteSentence(fa))
        return false;
    if (value[indexPointer] == "BEGIN" && !testCombined(fa))
        return false;
    return true;
}

bool CP::testAssignment(int lastId)
{
    int fa = addNode(lastId, "ASSIGNMENT");
    if (indexPointer > value.size())
        return false;
    if (type[indexPointer] != 4)
        return false;
    addNode(fa);
    if (value[indexPointer] != ":=")
        return false;
    addNode(fa);
    Addr addrs = findAd(value[indexPointer - 2], false);

    if (addrs.lo == -1)
        return false;
    if (!testExpression(fa))
        return false;
    pushInstr("STO", addrs.lo, addrs.addrs);
    return true;
}

bool CP::testCombined(int lastId)
{
    int fa = addNode(lastId, "COMBINED");
    if (indexPointer > value.size())
        return false;
    if (value[indexPointer] != "BEGIN")
        return false;
    addNode(fa);
    if (!testSentence(fa))
        return false;
    for ( ; value[indexPointer] == ";" ; ) {
        addNode(fa);
        if (!testSentence(fa)) {
            return false;
        }
    }
    if (value[indexPointer] != "END")
        return false;
    addNode(fa);
    return true;
}

bool CP::testCondition(int lastId)
{
    int fa = addNode(lastId, "CONDITION");
    if (indexPointer > value.size())
        return false;
    if (value[indexPointer] == "ODD") {
        addNode(fa);
        if (!testExpression(fa)) {
            return false;
        }
        pushInstr("OPR", 0, 1);
    } else {
        if (!testExpression(fa)) {
            return false;
        }
        std::string nowOP = value[indexPointer];
        if (!testRelationOp(fa)) {
            return false;
        }
        if (!testExpression(fa)) {
            return false;
        }
        if (nowOP == "=")
            pushInstr("OPR", 0, 2);
        else if (nowOP == "#")
            pushInstr("OPR", 0, 3);
        else if (nowOP == "<")
            pushInstr("OPR", 0, 4);
        else if (nowOP == "<=")
            pushInstr("OPR", 0, 5);
        else if (nowOP == ">")
            pushInstr("OPR", 0, 6);
        else if (nowOP == ">=")
            pushInstr("OPR", 0, 7);
    }
    return true;
}

bool CP::testExpression(int lastId)
{
    int fa = addNode(lastId, "EXPRESSION");
    if (indexPointer > value.size())
        return false;
    bool negative = false;
    if (value[indexPointer] == "+" || value[indexPointer] == "-") {
        if (value[indexPointer] == "-")
            negative = true;
        addNode(fa);
    }
    if (!testItem(fa))
        return false;
    if (negative) {
        pushInstr("OPR", 0, 8);
    }
    for ( ; value[indexPointer] == "+" || value[indexPointer] == "-" ; ) {
        bool plus;
        if (value[indexPointer] == "+")
            plus = true;
        else
            plus = false;
        addNode(fa);
        if (!testItem(fa)) {
            return false;
        }
        if (plus)
            pushInstr("OPR", 0, 9);
        else
            pushInstr("OPR", 0, 10);
    }
    return true;
}

bool CP::testItem(int lastId)
{
    int fa = addNode(lastId, "ITEM");
    if (indexPointer > value.size())
        return false;
    if (!testFactor(fa))
        return false;
    for ( ; value[indexPointer] == "*" || value[indexPointer] == "/" ; ) {
        bool mul;
        if (value[indexPointer] == "*")
            mul = true;
        else
            mul = false;
        addNode(fa);
        if (!testFactor(fa)) {
            return false;
        }
        if (mul)
            pushInstr("OPR", 0, 11);
        else
            pushInstr("OPR", 0, 12);
    }
    return true;
}

bool CP::testFactor(int lastId)
{
    int fa = addNode(lastId, "FACTOR");
    if (indexPointer > value.size())
        return false;
    if (value[indexPointer] == "(") {
        addNode(fa);
        if (!testExpression(fa)) {
            return false;
        }
        if (value[indexPointer] != ")") {
            return false;
        } else {
            addNode(fa);
            return true;
        }
    }
    if (type[indexPointer] == 4) {
        Addr addrs = findAd(value[indexPointer], false);
        if (addrs.lo == -1 && addrs.addrs == -1) {
            return false;
        }
        if (addrs.lo == -1) {
            pushInstr("LIT", 0, addrs.addrs);
        } else {
            pushInstr("LOD", addrs.lo, addrs.addrs);
        }
        addNode(fa);
        return true;
    }
    if (type[indexPointer] == 3) {
        pushInstr("LIT", 0, atoi(value[indexPointer].c_str()));
        addNode(fa);
        return true;
    }
    return false;
}

bool CP::testRelationOp(int lastId)
{
    if (indexPointer > value.size())
        return false;
    if (value[indexPointer] == "=" || value[indexPointer] == "#" || value[indexPointer] == "<"
        || value[indexPointer] == "<=" || value[indexPointer] == ">" || value[indexPointer] == ">=") {
        addNode(lastId);
        return true;
    } else
        return false;
}

bool CP::testIfSentence(int lastId)
{
    int fa = addNode(lastId, "IFSENTENCE");
    if (indexPointer > value.size())
        return false;
    if (value[indexPointer] != "IF")
        return false;
    addNode(fa);
    if (!testCondition(fa))
        return false;
    pushInstr("JPC", 0, 0);
    int index = instrSet.size() - 1;
    if (value[indexPointer] != "THEN")
        return false;
    addNode(fa);
    if (!testSentence(fa))
        return false;
    instrSet[index].addrs = instrSet.size();
    return true;
}

bool CP::testCallSentence(int lastId)
{
    int fa = addNode(lastId, "CALLSENTENCE");
    if (indexPointer > value.size())
        return false;
    if (value[indexPointer] != "CALL")
        return false;
    addNode(fa);
    if (type[indexPointer] != 4)
        return false;
    Addr addrs = findAd(value[indexPointer], true);
    if (addrs.lo == -1 && addrs.addrs == -1)
        return false;
    pushInstr("CAL", addrs.lo, addrs.addrs);
    addNode(fa);
    return true;
}

bool CP::testWhileSentence(int lastId)
{
    int fa = addNode(lastId, "WHILESENTENCE");
    if (indexPointer > value.size())
        return false;
    if (value[indexPointer] != "WHILE")
        return false;
    addNode(fa);
    int loop = instrSet.size();
    if (!testCondition(fa))
        return false;
    int jump = instrSet.size();
    pushInstr("JPC", 0, 0);
    if (value[indexPointer] != "DO")
        return false;
    addNode(fa);
    if (!testSentence(fa))
        return false;
    pushInstr("JMP", 0, loop);
    instrSet[jump].addrs = instrSet.size();
    return true;
}

bool CP::testReadSentence(int lastId)
{
    int fa = addNode(lastId, "READSENTENCE");
    if (indexPointer > value.size())
        return false;
    if (value[indexPointer] != "READ")
        return false;
    addNode(fa);
    if (value[indexPointer] != "(")
        return false;
    addNode(fa);
    if (type[indexPointer] != 4)
        return false;
    pushInstr("OPR", 0, 13);
    Addr addrs = findAd(value[indexPointer], false);
    if (addrs.addrs == -1 && addrs.lo == -1)
        return false;
    if (addrs.lo == -1)
        return false;
    pushInstr("STO", addrs.lo, addrs.addrs);
    addNode(fa);
    for ( ; value[indexPointer] == "," ; ) {
        addNode(fa);
        if (type[indexPointer] != 4) {
            return false;
        }
        pushInstr("OPR", 0, 13);
        Addr addrs = findAd(value[indexPointer], false);
        if (addrs.addrs == -1 && addrs.lo == -1) {
            return false;
        }
        if (addrs.lo == -1) {
            return false;
        }
        pushInstr("STO", addrs.lo, addrs.addrs);
        addNode(fa);
    }
    if (value[indexPointer] != ")")
        return false;
    addNode(fa);
    return true;
}

bool CP::testWriteSentence(int lastId)
{
    int fa = addNode(lastId, "WRITESENTENCE");
    if (indexPointer > value.size())
        return false;
    if (value[indexPointer] != "WRITE")
        return false;
    addNode(fa);
    if (value[indexPointer] != "(")
        return false;
    addNode(fa);
    if (type[indexPointer] != 4)
        return false;
    Addr addrs = findAd(value[indexPointer], false);
    if (addrs.addrs == -1 && addrs.lo == -1)
        return false;
    if (addrs.lo == -1) {
        pushInstr("LIT", 0, addrs.addrs);
    } else {
        pushInstr("LOD", addrs.lo, addrs.addrs);
    }
    pushInstr("OPR", 0, 14);
    addNode(fa);
    for ( ; value[indexPointer] == "," ; ) {
        addNode(fa);
        if (type[indexPointer] != 4) {
            return false;
        }
        Addr addrs = findAd(value[indexPointer], false);
        if (addrs.addrs == -1 && addrs.lo == -1) {
            return false;
        }
        if (addrs.lo == -1) {
            pushInstr("LIT", 0, addrs.addrs);
        } else {
            pushInstr("LOD", addrs.lo, addrs.addrs);
        }
        pushInstr("OPR", 0, 14);
        addNode(fa);
    }
    if (value[indexPointer] != ")")
        return false;
    addNode(fa);
    return true;
}

bool CP::testEmptySentence(int lastId) {
    addNode(lastId, "EMPTY");
    return false;
}

int main()
{
    freopen("program.code", "w", stdout);
    CP lab;
    lab.inputString();
    lab.lexicalAnalysis();
    lab.wordCheck();
    for (auto& item : lab.word) {
        lab.type.push_back(item.type);
        lab.value.push_back(item.value);
    }
    if (lab.testProgram()) {
        lab.printInstr();
    } else {
        std::cout << "Syntax Error" << std::endl;
        return -1;
    }
    return 0;
}
